#include "syscall.h"

STATIC void ClearScreen(void);

STATIC void ClearScreen(void) {
  RtlSetMemory((LPVOID)0xC00B8000, 0x17001700, 4160);
}

STATIC WORD GetCursorLoc(void) {
  WORD wLoc;
  WRITE_PORT_BYTE(0x3D4, 0xF);
  READ_PORT_BYTE(0x3D5, *(LPBYTE)&wLoc);
  WRITE_PORT_BYTE(0x3D4, 0xE);
  READ_PORT_BYTE(0x3D5, *((LPBYTE)&wLoc + 1));
  return wLoc;
}

STATIC void SetCursorLoc(WORD wLoc) {
  WRITE_PORT_BYTE(0x3D4, 0xF);
  WRITE_PORT_BYTE(0x3D5, *(LPBYTE)&wLoc);
  WRITE_PORT_BYTE(0x3D4, 0xE);
  WRITE_PORT_BYTE(0x3D5, *((LPBYTE)&wLoc + 1));
}

STATIC void PutString(const LPSTR lpszMsg) {
  WORD wPos = GetCursorLoc();
  register DWORD i;
  for (i = 0; lpszMsg[i]; i++) {
    if (lpszMsg[i] == '\n') {
      wPos = wPos / 80 * 80 + 80;
      continue;
    } else
      *(BYTE *)(DWORD_PTR)(0xC00B8000 + (wPos++) * 2) = lpszMsg[i];
    if (wPos >= 2000) {
      RtlCopyMemory((LPVOID)0xC00B8000, (LPVOID)0xC00B80A0, 4000);
      wPos -= 80;
    }
  }
  SetCursorLoc(wPos);
}

void SyscallInitialize(void) {
  SyscallTable[0] = ClearScreen;
  SyscallTable[1] = GetCursorLoc;
  SyscallTable[2] = SetCursorLoc;
  SyscallTable[3] = PutString;
}
